﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace An_Im.Theme.Custom
{
    public class AnTextBox : TextBox
    {

        public event EventHandler InputFinished;

        /// <summary>
        /// 非法弥补值。
        /// </summary>
        public string EmptyReplaceString { get; set; } = "0";

        public static string InfinityString { get; set; } = float.PositiveInfinity.ToString();
        private char infinity = InfinityString[0];

        public float MinValue { get; set; } = 0;
        public float MaxValue { get; set; } = 65535;

        /// <summary>
        /// 只限制数字的输入。
        /// </summary>
        public bool OnlyNumber
        {
            get { return (bool)GetValue(OnlyNumberProperty); }
            set { SetValue(OnlyNumberProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OnlyNumber.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OnlyNumberProperty =
            DependencyProperty.Register("OnlyNumber", typeof(bool), typeof(AnTextBox), new PropertyMetadata(false));

        //protected override void OnMouseDown(MouseButtonEventArgs e)
        //{
        //    SelectAll();
        //    base.OnMouseDown(e);
        //}


        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            SelectAll();
            base.OnMouseLeftButtonDown(e);
        }

        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            //SelectAll();
            base.OnPreviewMouseDown(e);
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            //if (OnlyNumber)
            //{
            //    if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) ||
            //        (e.Key >= Key.D0 && e.Key <= Key.D9) ||
            //        e.Key == Key.Back ||
            //        e.Key == Key.Left || e.Key == Key.Right || e.get|| e.Key == Key.Enter || e.Key == Key.LeftShift || e.Key == Key.RightShift)
            //    {
            //        if (e.KeyboardDevice.Modifiers != ModifierKeys.None)
            //        {
            //            e.Handled = true;
            //        }
            //    }
            //    else
            //    {
            //        e.Handled = true;
            //    }
            //}

            base.OnPreviewKeyDown(e);
        }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            SelectAll();
            base.OnGotFocus(e); 
        }

        protected float GetValidTextValue(out string outputText)
        {
            float val;
            if (Text.Length == 0)
            {
                outputText = EmptyReplaceString;
                return float.Parse(EmptyReplaceString);
            }
            else
            {
                var textarr = Text.ToCharArray();
                var empty = string.Empty;
                bool hasdot = false;
                bool isinf = false;
                for (int i = 0; i < textarr.Length; i++)
                {
                    if (textarr[i] == '.' && hasdot == false)
                    {
                        hasdot = true;
                        empty += textarr[i];
                    }
                    else if (textarr[i] <= '9' && textarr[i] >= '0')
                    {
                        empty += textarr[i];
                    }
                    else if (textarr[i] == infinity)
                        isinf = true;

                }

                outputText = empty;

                if (isinf)
                    outputText = float.PositiveInfinity.ToString();
                if (Text.Length == 0)
                {
                    outputText = EmptyReplaceString;
                    return float.Parse(EmptyReplaceString);
                }
                else
                {
                    val = float.Parse(outputText);
                    if (val > MaxValue)
                        val = MaxValue;
                    else if (val < MinValue)
                        val = MinValue;
                    outputText = val.ToString();
                }
                return val;
            }
        }

        protected float GetValidTextValue()
        {
            float val;
            string outputText;
            if (Text.Length == 0)
            {
                return float.Parse(EmptyReplaceString);
            }
            else
            {
                var textarr = Text.ToCharArray();
                var empty = string.Empty;
                bool hasdot = false;
                bool isinf = false;
                for (int i = 0; i < textarr.Length; i++)
                {
                    if (textarr[i] == '.' && hasdot == false)
                    {
                        hasdot = true;
                        empty += textarr[i];
                    }
                    else if (textarr[i] <= '9' && textarr[i] >= '0')
                    {
                        empty += textarr[i];
                    }
                    else if (textarr[i] == infinity)
                        isinf = true;

                }

                outputText = empty;

                if (isinf)
                    outputText = float.PositiveInfinity.ToString();
                if (Text.Length == 0)
                {
                    return float.Parse(EmptyReplaceString);
                }
                else
                {
                    val = float.Parse(outputText);
                    if (val > MaxValue)
                        val = MaxValue;
                    else if (val < MinValue)
                        val = MinValue;
                }
                return val;
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.Key == Key.Enter)
            {
                if (OnlyNumber)
                {
                    GetValidTextValue(out var str);
                    Text = str;
                    InputFinished?.Invoke(this, EventArgs.Empty);
                }
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
            }
        }

        static AnTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(AnTextBox), new FrameworkPropertyMetadata(typeof(AnTextBox)));
        }
    }
}
